

#ifndef __TRANSFORMERHANDLE_H__
#define __TRANSFORMERHANDLE_H__

#include <math/color.h>
#include <scene/entitynode.h>
#include <btBulletDynamicsCommon.h>
#include <utils/transformer.h>

class ceMesh;
struct iDevice;


enum TransformerCoordinates
{
  TransformerCoordinates_Global,
  TransformerCoordinates_Local
};

enum TransformerMode
{
  TransformerMode_Translation,
  TransformerMode_Rotation
};


class TransformerHandle
{
public:
	enum Axis
	{
		Axis_X,
		Axis_Y,
		Axis_Z,
		Axis_COUNT
	};
private:

  TransformerCoordinates  _coordinates;

	ceColor4f			_colors[Axis_COUNT];

	Axis					_axis;

  ceMatrix4f    _originMatrix;
  ceMatrix4f    _useMatrix;
  ceMatrix4f    _invUseMatrix;

	ceEntityNode	*_entity;
	ceGeometry		*_geometry;

  ceTransformer *_transformer;

protected:
  TransformerHandle (Axis axis);
	virtual ceMesh* CreateMesh (iDevice* device) = 0;
  virtual iEffect* GetEffect (iDevice* device) = 0;

public:
	const ceColor4f& GetColor () const;
	const ceColor4f& GetColor (Axis axis) const;

  void SetOriginMatrix (const ceMatrix4f& origin);
  const ceMatrix4f& GetOriginMatrix () const;
  const ceMatrix4f& GetUseMatrix () const;
  const ceMatrix4f& GetInvUseMatrix () const;
  void UpdateUseMatrix ();
  void UpdateOriginMatrix ();
  void UpdateMatrices ();


  void SetTransformerCoordinates (TransformerCoordinates mode);
  TransformerCoordinates GetTransformerCoordinates () const;

  void SetTransformer (ceTransformer* transformer);
  ceTransformer* GetTransformer ();

  ceEntityNode* GetEntity () const;

	Axis GetAxis () const;

	void Initialize (iDevice* device);

  virtual bool Test (const ceRay& ray, float &distance) = 0;
  virtual void Transform (const ceRay& from, const ceRay& to) = 0;
};


class TranslationTransformerHandle : public TransformerHandle
{
private:
  float _length;
  ceVector3f  _direction;

  ceVector3f GetPosition (const ceRay& ray);

protected:
	virtual ceMesh* CreateMesh (iDevice* device);
  virtual iEffect* GetEffect (iDevice* device);
public:
	TranslationTransformerHandle (Axis axis);
  void SetLength (float length);

  virtual bool Test (const ceRay& ray, float &distance);
  virtual void Transform (const ceRay& from, const ceRay& to);

};




class RotationTransformerHandle : public TransformerHandle
{
private:
  float _length;
  ceVector3f  _direction;

  ceVector3f GetDirection (const ceRay& ray);

protected:
  virtual ceMesh* CreateMesh (iDevice* device);
  virtual iEffect* GetEffect (iDevice* device);

public:
  RotationTransformerHandle (Axis axis);
  void SetLength (float length);

  virtual bool Test (const ceRay& ray, float &distance);
  virtual void Transform (const ceRay& from, const ceRay& to);

};




class Transformer
{
public:

protected:
  std::vector<TransformerHandle*> _handles;
  std::vector<ceEntityNode*>      _entities;

  TransformerHandle*            _active;

  TransformerMode               _mode;

  Transformer (TransformerMode mode);

  void AddHandle (TransformerHandle* handle);
public:

  virtual bool Test (const ceRay& ray);
  virtual void Transform (const ceRay& from, const ceRay& to);
  void UpdateOriginMatrix ();
  void UpdateUseMatrix ();
  void ClearActive ();
  bool IsActive () const;

  void SetTransformerCoordinates (TransformerCoordinates coordinates);
  TransformerMode GetTransformerMode () const;

  std::vector<ceEntityNode*>& GetEntities ();

  void SetTransformer (ceTransformer* transformer);
};

class TranslationTransformer : public Transformer
{
public:
  TranslationTransformer ();

};


class RotationTransformer : public Transformer
{
public:
  RotationTransformer ();

};

#endif /* !__TRANSFORMERHANDLE_H__ */
